package com.kkb.retailer.center.filter;


import com.kkb.retailer.center.common.http.DefinitionException;
import com.kkb.retailer.center.common.util.JwtUtil;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.SignatureException;
import io.jsonwebtoken.UnsupportedJwtException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;


public class JWTAuthenticationFilter extends BasicAuthenticationFilter {

    private static final Logger logger = LoggerFactory.getLogger(JWTAuthenticationFilter.class);

    public JWTAuthenticationFilter(AuthenticationManager authenticationManager){
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        //获取Token信息
        String header = request.getHeader("Authorization");
        if(header==null||!header.startsWith("Bearer")){
            chain.doFilter(request,response);
            return;
        }

        //校验Token是否正确
        UsernamePasswordAuthenticationToken authenticationToken = this.getAuthentication(request);
        //Token校验失败
        if(authenticationToken==null){
            chain.doFilter(request,response);
            return;
        }

        //如果Token正确，设置Token到上下文中
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        chain.doFilter(request,response);
    }

    /**
     * 校验Token值是否正确
     * @param request
     * @return
     */
    private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request){
        String token = request.getHeader("Authorization");
        if(token==null || token.isEmpty()){
            throw new DefinitionException("Token为空");
        }

        try{
            String user = JwtUtil.parseToken(token).getSubject();
            //如果Token值正确，则返回认证信息
            if(user!=null){
                return new UsernamePasswordAuthenticationToken(user,user,new ArrayList<>());
            }
        }catch (ExpiredJwtException e) {
            logger.error("Token已过期: {} " + e);
        } catch (UnsupportedJwtException e) {
            logger.error("Token格式错误: {} " + e);
            throw new DefinitionException("Token格式错误");
        } catch (MalformedJwtException e) {
            logger.error("Token没有被正确构造: {} " + e);
            throw new DefinitionException("Token没有被正确构造");
        } catch (SignatureException e) {
            logger.error("签名失败: {} " + e);
            throw new DefinitionException("签名失败");
        } catch (IllegalArgumentException e) {
            logger.error("非法参数异常: {} " + e);
            throw new DefinitionException("非法参数异常");
        }

        //校验Token失败
        return null;
    }


}
